package com.jingge.home.framework;

import com.jingge.home.util.LocalCacheManager;
import com.jingge.home.util.wx.WxMessageBuilder;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.message.WxCpMessageHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * AI消息处理器
 *
 * @author Yongxiang
 * @date 2025-07-30 13:38
 * @email 1158055613@qq.com
 */
@Slf4j
@Component
public class AiMsgHandler implements WxCpMessageHandler {
	@Autowired
	private LocalCacheManager<String, String> msgCache;

	@Value("${wechat.aiUrl}")
	private String AI_URL;

	@Value("${wechat.currentAiAPIKey}")
	private String defaultApiKey;
	@Override
	public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage,
	                                Map<String, Object> context,
	                                WxCpService wxCpService,
	                                WxSessionManager sessionManager) throws WxErrorException {
		String content = wxMessage.getContent();
		String to = wxMessage.getFromUserName();
		String from = wxMessage.getToUserName();
		String receiveMsgId = String.valueOf(wxMessage.getMsgId());
		//如果正有消息在处理
		if (DifyConversationStreamChatClient.isUserMsgHandling(to)) {
			return WxMessageBuilder.buildTextMessage("我正在努力处理你的上个问题，请稍等一下再问我哟。", from, to);
		}
		//如果服务被锁定
		if (msgCache.exist(CacheKeyConstant.LOCK_KEY)) {
			return WxMessageBuilder.buildTextMessage("抱歉！管理员已经锁定对话服务，详细情况请咨询公众号管理员", from, to);
		}
		//如果没有授权
		if (!CacheKeyConstant.withAuth(to)) {
			return WxMessageBuilder.buildTextMessage("您好，您还没有得到授权与我对话，你可以通过指令“c:a:授权码”来进行授权", from, to);
		}
		StringBuilder res = new StringBuilder();
		msgCache.set(CacheKeyConstant.RECEIVE_MSG_ID_PREFIX + receiveMsgId, "1", 5, TimeUnit.MINUTES);
		String cachePicUrl = msgCache.get(CacheKeyConstant.PIC_PREFIX + to);
		String currentApiKey = msgCache.get(CacheKeyConstant.CURRENT_API_KEY);
		if (StringUtils.isEmpty(currentApiKey)) {
			log.info("缓存的API已过期，尝试使用默认的API KEY");
			currentApiKey = defaultApiKey;
			msgCache.set(CacheKeyConstant.CURRENT_API_KEY, defaultApiKey, 365, TimeUnit.DAYS);
		}
		DifyConversationStreamChatClient.sendStreamingMessage(content, AI_URL + "/chat-messages", cachePicUrl, msgCache.exist(CacheKeyConstant.CONVERSATION_ID_PREFIX + to) ? msgCache.get(CacheKeyConstant.CONVERSATION_ID_PREFIX + to) : "", to, currentApiKey, 14, receiveMsgId, event -> {
			switch (event.getEventType()) {
				case "message":
					DifyConversationStreamChatClient.MessageEvent msgEvent = (DifyConversationStreamChatClient.MessageEvent) event;
					log.info("收到消息片段: {}", msgEvent.getAnswer());
					res.append(msgEvent.getAnswer());
					msgCache.set(CacheKeyConstant.CONVERSATION_ID_PREFIX + to, (msgEvent.getConversationId()), 24, TimeUnit.HOURS);
					break;
				case "message_end":
					log.info("对话结束");
					DifyConversationStreamChatClient.MessageEndEvent msgEndEvent = (DifyConversationStreamChatClient.MessageEndEvent) event;
					msgCache.set(CacheKeyConstant.CONVERSATION_ID_PREFIX + to, (msgEndEvent.getConversationId()), 24, TimeUnit.HOURS);
					break;
				case "workflow_started":
					log.info("工作流开始: " + event.getRawData());
					break;
				case "error":
					log.info("错误: {}", event.getRawData());
					res.append("\n服务发生了些问题，请联系公众号管理员\n");
					break;
				case "timeoutMsg":
					log.info("超时");
					res.append("\n回复\"m\"或者\"@").append(event.getRawData()).append("\"获取完整消息");
					break;
				case "override":
					log.info("满载");
					res.append("系统有点忙哦，请稍后再试");
					break;
				case "parse_error":
					log.info("发生异常");
					res.append("\n").append(event.getRawData());
					break;
			}
		});
		log.info("回复消息：{}", res);
		return WxMessageBuilder.buildTextMessage(res.toString(), from, to);
	}
}
